package com.gnar.dis;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.BitmapFactory.Options;
import android.hardware.SensorManager;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import com.gnar.dis.Sprite.type;


public class GameView extends View  {

	// Images
	// TODO: Images should be defined in XML and aggregated to their owners - CP
	private Bitmap mBackground1;
	private Bitmap mBackground2;
	private Bitmap mBackground3;
	private Bitmap mTest;
	private Bitmap mDinoship;
	private Bitmap mBomb;
	private Bitmap mHuman;
	private Bitmap mGround;
	
	// List of Sprites
	// TODO: Drawing should be done in a single sorted array, sorted by depth - CP
	// TODO: Is a seperate class for this necessary?
	private ArrayList<Sprite> spriteList;
	private ArrayList<Sprite> enemyList; 
	private ArrayList<Sprite> backgroundList;
	private ArrayList<Sprite> backgroundList2;
	private ArrayList<Sprite> backgroundList3;
	
	// Device Metrics
	// TODO: What are these used for? Where do they belong?
	private float mXDpi;
	private float mYDpi;
	private float mMetersToPixelsX;
	private float mMetersToPixelsY;
	private float mX;
	
	// Device Manager objects
	private WindowManager mWindowManager;
	private Display mDisplay;
	private EventHandler mEventHandler;
	private SensorManager mSensorManager;
	
	// Time Stamps
	private long mSensorTimeStamp;
	private long mCpuTimeStamp;
	
	// TODO: all update functions should take deltat as a parameter
	// DeltaT Variables
	private long mLastT;
	private float mLastDeltaT;
	
	public GameView(Context context) {
		super(context);
		
		// Get an instance of the WindowManager
        mWindowManager = (WindowManager) context.getSystemService(context.WINDOW_SERVICE);
        mDisplay = mWindowManager.getDefaultDisplay();
        
        // Get an instance of the SensorManager
        mSensorManager = (SensorManager) context.getSystemService(context.SENSOR_SERVICE);
        
        // Set metrics from device
		DisplayMetrics metrics = new DisplayMetrics();
		mWindowManager.getDefaultDisplay().getMetrics(metrics);
		mXDpi = metrics.xdpi;
        mYDpi = metrics.ydpi;
        mMetersToPixelsX = mXDpi / 0.0254f;
        mMetersToPixelsY = mYDpi / 0.0254f;
        
        // Create EventHandler from Display
        mEventHandler = new EventHandler(mDisplay, mSensorManager);
        
        // Set Bitmap options
        Options opts = new Options();
        opts.inDither = true;
        opts.inPreferredConfig = Bitmap.Config.RGB_565;
        
        // Grab image resources
        mBackground1 = BitmapFactory.decodeResource(getResources(), R.drawable.background_1, opts);
        mBackground2 = BitmapFactory.decodeResource(getResources(), R.drawable.background_2, opts);
        mBackground3 = BitmapFactory.decodeResource(getResources(), R.drawable.background_3, opts);
        mDinoship = BitmapFactory.decodeResource(getResources(), R.drawable.dinoship, opts);
        mBomb = BitmapFactory.decodeResource(getResources(), R.drawable.bomb, opts);
        mHuman = BitmapFactory.decodeResource(getResources(), R.drawable.stach, opts);
        mGround = BitmapFactory.decodeResource(getResources(), R.drawable.ground, opts);
        
        // Create list of sprites
        spriteList = new ArrayList<Sprite>();
        enemyList = new ArrayList<Sprite>();
        backgroundList = new ArrayList<Sprite>();
        backgroundList2 = new ArrayList<Sprite>();
        backgroundList3 = new ArrayList<Sprite>();
        
        spriteList.add(new Ship(mDinoship, 100f, 100f));
        backgroundList.add(new BackGround(mBackground1, 0, 0).setAccelX(4f));
        backgroundList.add(new BackGround(mBackground1, -799, 0).setAccelX(4f));
        backgroundList2.add(new BackGround(mBackground2, 0, 0).setAccelX(3f));
        backgroundList2.add(new BackGround(mBackground2, -775, 0).setAccelX(3f));
        backgroundList3.add(new BackGround(mBackground3, 0, 0).setAccelX(1f));
        backgroundList3.add(new BackGround(mBackground3, -799, 0).setAccelX(1f));

        
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int action = event.getAction();
		
		if (action == MotionEvent.ACTION_DOWN) {
			spriteList.add(new Bomb(mBomb, spriteList.get(0).getPosX() + 50, spriteList.get(0).getPosY() + 76));
			
		}
        return true;
    }
	
	@Override
    protected void onDraw(Canvas canvas) {
		
		// Random Gen Human Sprites
		genHumans();
			
		// Updates the sprites positions
		collision();
		update();

		// Derp Derp Derp
		draw();
		

		// Make sure every redraws onDraw next cycle
		invalidate(); 

	}

	public void genHumans(){

		if( (int)(Math.random() * 100) < 4){
			enemyList.add(new Human(mHuman, -10 , 420));
		}
	}
	
	public void draw(){
	
		// Draw Backgrounds	
		for (Sprite bg : backgroundList3){
			canvas.drawBitmap(bg.getImage(), bg.getPosX(), bg.getPosY() , null);
		}
		for (Sprite bg : backgroundList2){
			canvas.drawBitmap(bg.getImage(), bg.getPosX(), bg.getPosY() , null);
		}
		for (Sprite bg : backgroundList){
			canvas.drawBitmap(bg.getImage(), bg.getPosX(), bg.getPosY() , null);
		}
		
		if (backgroundList.size() < 2){
			backgroundList.add(new BackGround(mBackground1, -775, 0).setAccelX(4f));
		}
		if (backgroundList2.size() < 2){
			backgroundList2.add(new BackGround(mBackground2, -775, 0).setAccelX(3f));
		}
		if (backgroundList3.size() < 2){
			backgroundList3.add(new BackGround(mBackground3, -775, 0).setAccelX(1f));
		}

		// Draw images
		for (Sprite currentSprite : enemyList) {
			canvas.drawBitmap(currentSprite.getImage(), currentSprite.getPosX(), currentSprite.getPosY() , null);
		} 
		
		for (Sprite currentSprite : spriteList) {
			canvas.drawBitmap(currentSprite.getImage(), currentSprite.getPosX(), currentSprite.getPosY() , null);
		} 

	}


	public void collision(){
		// Collision
		for (Sprite currentSprite : spriteList) {
			for (Sprite currentEnemy : enemyList){
				if (Rect.intersects(currentSprite.getRect(),currentEnemy.getRect())){
					currentEnemy.destroy();
				}
			}
		}
	}
	
	public void update() {
		
		// Update Background
		for (Sprite bg : backgroundList){ 
			bg.update(mEventHandler);
		}
		for (Sprite bg : backgroundList2){ 
			bg.update(mEventHandler);
		}
		for (Sprite bg : backgroundList3){ 
			bg.update(mEventHandler);
		}
		
		// Update sprites
		for (Sprite currentSprite : spriteList) {
			currentSprite.update(mEventHandler);
		}
		for (Sprite currentEnemy : enemyList){
			currentEnemy.update(mEventHandler);
		}
		
		
		//Delete old Background
		for (int i = 0 ; i < backgroundList.size(); i++){
			if (backgroundList.get(i).getType() == type.DEST_OB){
				backgroundList.remove(i);
			}
		}
		for (int i = 0 ; i < backgroundList2.size(); i++){
			if (backgroundList2.get(i).getType() == type.DEST_OB){
				backgroundList2.remove(i);
			}
		}
		for (int i = 0 ; i < backgroundList3.size(); i++){
			if (backgroundList3.get(i).getType() == type.DEST_OB){
				backgroundList3.remove(i);
			}
		}
		// Remove Sprites
		for (int i = 0 ; i < spriteList.size(); i++){
			if (spriteList.get(i).getType() == type.DEST_OB){
				spriteList.remove(i);
			}
		}
		
		for (int i = 0 ; i < enemyList.size(); i++){
			if (enemyList.get(i).getType() == type.DEST_OB){
				enemyList.remove(i);
			}
		}
	}
}
